package com.geekhalo.lego.plugin.readfrom;

import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PropertyUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.geekhalo.lego.plugin.support.util.Utils.hasImports;

public class CreateReadFromMethod {
    private static final List<String> FILTER_NAMES = Arrays.asList("id", "events", "class");
    public static String create(Project project, PsiClass fromPsiClass, PsiClass targetPsiClass) {

        PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project)
                .getElementFactory();
        WriteCommandAction.runWriteCommandAction(project, ()->{
            // 将 import 语句添加到 PsiJavaFile 的 import 列表中
            PsiJavaFile javaFile = (PsiJavaFile) targetPsiClass.getContainingFile();
            PsiImportList importList = javaFile.getImportList();

            { // 导入 参数
                PsiClass psiClass = fromPsiClass;
                if (psiClass!=null && !hasImports(importList, psiClass)) {
                    importList.add(elementFactory.createImportStatement(psiClass));
                }
            }
        });

        Map<String, PsiMethod> setterMaps = new HashMap<>();
        for (PsiMethod method : targetPsiClass.getAllMethods()){
            if (method.getContainingClass() != targetPsiClass
                    &&method.getModifierList().hasModifierProperty(PsiModifier.PRIVATE)){
                continue;
            }
            if (PropertyUtil.isSimplePropertySetter(method)){
                String name = PropertyUtil.getPropertyName(method);
                setterMaps.put(name, method);
            }
        }
        StringBuilder stringBuilder = new StringBuilder("\n");
        stringBuilder.append("\t// 自动生成代码，勿动\n");
        stringBuilder
                .append("\tprivate void readFrom(").append(fromPsiClass.getName()).append(" source){\n");
        for (PsiMethod getter : fromPsiClass.getAllMethods()){
            if (PropertyUtil.isSimplePropertyGetter(getter)){
                String name = PropertyUtil.getPropertyName(getter);
                if (FILTER_NAMES.contains(name)){
                    continue;
                }
                if (!getter.getModifierList().hasModifierProperty(PsiModifier.PUBLIC)){
                    continue;
                }

                PsiMethod setter = setterMaps.get(name);

                if (setter == null){
                    stringBuilder.append("\t\t")
                            .append("// not setter for ").append(name).append("\n");
                }else {
                    stringBuilder.append("\t\tif(source.").append(getter.getName()).append("() != null){\n");
                    stringBuilder.append("\t\t\t")
                            .append("this.").append(setter.getName())
                            .append("(source.").append(getter.getName()).append("());\n");
                    stringBuilder.append("\t\t}\n");
                }
            }
        }
        stringBuilder.append("\t}");
        return stringBuilder.toString();
    }
}
